//
//  PlotV2ViewController.m
//  Fuel Log 4
//
//  Created by Olaf on 29.05.10.
//  Copyright 2010 olafgreck. All rights reserved.
//

#import "PlotV2ViewController.h"
#import "FuelLogAppDelegate.h"
#import "DebugOutput.h"


@implementation PlotV2ViewController

@synthesize dataForPlot;
@synthesize xAxisLabels;
@synthesize fillUps;
@synthesize beginIdx, endIdx;
@synthesize minDpf, maxDpf;

#pragma mark -
#pragma mark Do the math

-(void)doTheMath {
	// do the math first
	FuelLogAppDelegate *appDelegate = (FuelLogAppDelegate *)[[UIApplication sharedApplication] delegate];
	int prefUnits = [FuelLogAppDelegate pref].units;
	BOOL uk = (prefUnits == UK);
	BOOL norway = (prefUnits == NORWAY);
	BOOL inverted = (prefUnits == INV_METRIC || norway);
	xAxisLabels = [[NSMutableArray alloc] init];
	Gas *gas;
	for(; endIdx <= beginIdx && endIdx < appDelegate.pumps.count; ++endIdx) {
		gas = (Gas *)[appDelegate.pumps objectAtIndex:endIdx];
		if (gas.full) break;
	}
	for(; beginIdx >= endIdx && beginIdx >= 0; --beginIdx) {
		gas = (Gas *)[appDelegate.pumps objectAtIndex:beginIdx];
		if (gas.full) break;
	}
	float fuel = 0.0;
	float distance = gas.odometer;
	NSMutableArray *fillups = [NSMutableArray arrayWithCapacity:10];
	float dpf;
	minDpf = 9999999.0;
	maxDpf = 0.0;
	--beginIdx;
	NSMutableArray *contentArray = [NSMutableArray arrayWithCapacity:100];
	int i = 0;
	for(; beginIdx >= endIdx; --beginIdx) {
		gas = (Gas *)[appDelegate.pumps objectAtIndex:beginIdx];		
		fuel += gas.volume;
		if (gas.full) {
			dpf = (gas.odometer - distance) / fuel;
			if (inverted && dpf > 0.0) {
				if (norway) {
					dpf = 10.0 / dpf;
				} else {
					dpf = 100.0 / dpf;
				}
			} else if (uk) {
				dpf = dpf * UK_GALLON;
			}
			if (dpf < minDpf) minDpf = dpf;
			if (dpf > maxDpf) maxDpf = dpf;
			[fillups addObject:[NSNumber numberWithFloat:dpf]];
			id x = [NSNumber numberWithFloat:i];
			id y = [NSNumber numberWithFloat:dpf];
			[contentArray addObject:[NSMutableDictionary dictionaryWithObjectsAndKeys:x, @"x",  y, @"y", nil]];
			debug(@"x= %@, i = %f",x,i);
			debug(@"y= %f",dpf);
			distance = gas.odometer;
			[xAxisLabels addObject:[NSString stringWithFormat:@"%.1f",distance]];
			fuel = 0.0;
			++i;
		}
	}
	self.dataForPlot = contentArray;
	
	if (norway) {
		maxDpf = ceil(maxDpf*10) / 10.0;
		minDpf = floor(minDpf*10) / 10.0;
	} else {
		maxDpf = ceil(maxDpf);
		minDpf = floor(minDpf);
	}
	
}

#pragma mark -

-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
{
	if (toInterfaceOrientation != UIInterfaceOrientationPortraitUpsideDown) return YES;
	else return NO; 
}

#pragma mark -
#pragma mark Initialization and teardown

// Implement loadView to create a view hierarchy programmatically, without using a nib.
- (void)loadView {
	debug(@"in loadView");
	
	//	self.view = [[CPLayerHostingView alloc] initWithFrame:CGRectMake(0, 0, 320, 480)];
	self.view = [[CPLayerHostingView alloc]initWithFrame:[UIScreen mainScreen].bounds];
}

-(void)addLabelsX{
	CPXYAxisSet *axisSet = (CPXYAxisSet *)graph.axisSet;
	CPXYAxis *x = axisSet.xAxis;
	x.labelRotation = M_PI/4;
	x.labelingPolicy = CPAxisLabelingPolicyNone;
 	NSUInteger labelLocation = 0;
	NSMutableArray *customLabels = [[NSMutableArray alloc] initWithCapacity:[xAxisLabels count]];
 	for (NSDictionary * xYCordiante in self.dataForPlot)
	{
		NSNumber * tickLocation = [xYCordiante valueForKey:@"x"];
		CPAxisLabel *newLabel = [[CPAxisLabel alloc] initWithText: [xAxisLabels objectAtIndex:labelLocation++] 
														textStyle:x.labelTextStyle];
		newLabel.tickLocation =  [tickLocation decimalValue];
		newLabel.offset = x.labelOffset + x.majorTickLength;
		newLabel.rotation = M_PI/4;
		[customLabels addObject:newLabel];
		[newLabel release];
	}
	
	x.axisLabels =  [NSSet setWithArray:customLabels];
	
}

-(void)viewDidLoad 
{
    [super viewDidLoad];
	[self doTheMath];
    // Create graph from theme
    graph = [[CPXYGraph alloc] initWithFrame:CGRectZero];
	CPTheme *theme = [CPTheme themeNamed:kCPDarkGradientTheme];
    [graph applyTheme:theme];
	CPLayerHostingView *hostingView = (CPLayerHostingView *)self.view;
    hostingView.hostedLayer = graph;
	graph.plotAreaFrame.masksToBorder = NO;
	
	graph.paddingLeft = 10.0;
	graph.paddingTop = 10.0;
	graph.paddingRight = 10.0;
	graph.paddingBottom = 10.0;
	/*
	 graph.paddingLeft = 70.0;
	 graph.paddingTop = 20.0;
	 graph.paddingRight = 20.0;
	 graph.paddingBottom = 80.0;
	 */
	
    // Setup plot space 
    CPXYPlotSpace *plotSpace = (CPXYPlotSpace *)graph.defaultPlotSpace;
    plotSpace.allowsUserInteraction = YES;
	float numberOfValuesX = [self.dataForPlot count]-1;
    plotSpace.xRange = [CPPlotRange plotRangeWithLocation:CPDecimalFromFloat(0.0) 
												   length:CPDecimalFromFloat(numberOfValuesX)];
    plotSpace.yRange = [CPPlotRange plotRangeWithLocation:CPDecimalFromFloat(0.0)
												   length:CPDecimalFromFloat(maxDpf)];
	/*
	 #pragma mark 	// autoscale
//	 [plotSpace scaleToFitPlots:[NSArray arrayWithObject:[graph plotAtIndex:0]]];
	 // crashes with __Terminating due to Uncaught exception__ 
	*/	
//	[plotSpace scaleToFitPlots:graph];
	CPPlotRange *xRange = plotSpace.xRange;
	[xRange expandRangeByFactor:CPDecimalFromDouble(1.3)];
	plotSpace.xRange = xRange;
	CPPlotRange *yRange = plotSpace.yRange;
	[yRange expandRangeByFactor:CPDecimalFromDouble(1.3)];
	plotSpace.yRange = yRange;
	
	
    // Axes
	CPXYAxisSet *axisSet = (CPXYAxisSet *)graph.axisSet;
    CPXYAxis *x = axisSet.xAxis;
    x.majorIntervalLength = CPDecimalFromFloat(numberOfValuesX);
    x.orthogonalCoordinateDecimal = CPDecimalFromFloat(0);
    x.minorTicksPerInterval = numberOfValuesX;
/*	x.axisLineStyle = nil;
    x.majorTickLineStyle = nil;
    x.minorTickLineStyle = nil;
	x.title = @"Distance";
	x.titleLocation = CPDecimalFromFloat(7.5f);
	x.titleOffset = 55.0f;
 */
	/* 	NSArray *exclusionRanges = [NSArray arrayWithObjects:
	 [CPPlotRange plotRangeWithLocation:CPDecimalFromFloat(1.99) length:CPDecimalFromFloat(0.02)], 
	 [CPPlotRange plotRangeWithLocation:CPDecimalFromFloat(0.99) length:CPDecimalFromFloat(0.02)],
	 [CPPlotRange plotRangeWithLocation:CPDecimalFromFloat(2.99) length:CPDecimalFromFloat(0.02)],
	 nil];
	 x.labelExclusionRanges = exclusionRanges;
	 */
    CPXYAxis *y = axisSet.yAxis;
    y.majorIntervalLength = CPDecimalFromFloat(10);
    y.orthogonalCoordinateDecimal = CPDecimalFromFloat(0);
    y.minorTicksPerInterval = 1;
	y.title = @"Consumption";
	y.titleOffset = 45.0f;
    y.titleLocation = CPDecimalFromFloat(150.0f);
	/*	exclusionRanges = [NSArray arrayWithObjects:
	 [CPPlotRange plotRangeWithLocation:CPDecimalFromFloat(1.99) length:CPDecimalFromFloat(0.02)], 
	 [CPPlotRange plotRangeWithLocation:CPDecimalFromFloat(0.99) length:CPDecimalFromFloat(0.02)],
	 [CPPlotRange plotRangeWithLocation:CPDecimalFromFloat(3.99) length:CPDecimalFromFloat(0.02)],
	 nil];
	 y.labelExclusionRanges = exclusionRanges;
	 */
	
	
	// Create a blue plot area
	CPScatterPlot *boundLinePlot = [[[CPScatterPlot alloc] init] autorelease];
    boundLinePlot.identifier = @"Blue Plot";
	boundLinePlot.dataLineStyle.miterLimit = 1.0f;
	boundLinePlot.dataLineStyle.lineWidth = 3.0f;
	boundLinePlot.dataLineStyle.lineColor = [CPColor blueColor];
    boundLinePlot.dataSource = self;
	[graph addPlot:boundLinePlot];
	
	// Do a blue gradient
	CPColor *areaColor1 = [CPColor colorWithComponentRed:0.3 green:0.3 blue:1.0 alpha:0.8];
    CPGradient *areaGradient1 = [CPGradient gradientWithBeginningColor:areaColor1 endingColor:[CPColor clearColor]];
    areaGradient1.angle = -90.0f;
    CPFill *areaGradientFill = [CPFill fillWithGradient:areaGradient1];
    boundLinePlot.areaFill = areaGradientFill;
    boundLinePlot.areaBaseValue = [[NSDecimalNumber zero] decimalValue];    
	
	// Add plot symbols
	CPLineStyle *symbolLineStyle = [CPLineStyle lineStyle];
	symbolLineStyle.lineColor = [CPColor blackColor];
	CPPlotSymbol *plotSymbol = [CPPlotSymbol ellipsePlotSymbol];
	plotSymbol.fill = [CPFill fillWithColor:[CPColor blueColor]];
	plotSymbol.lineStyle = symbolLineStyle;
    plotSymbol.size = CGSizeMake(10.0, 10.0);
    boundLinePlot.plotSymbol = plotSymbol;
	
	
#ifdef PERFORMANCE_TEST
    [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(changePlotRange) userInfo:nil repeats:YES];
#endif
	[self addLabelsX];
}

-(void)changePlotRange 
{
    // Setup plot space
    CPXYPlotSpace *plotSpace = (CPXYPlotSpace *)graph.defaultPlotSpace;
    plotSpace.xRange = [CPPlotRange plotRangeWithLocation:CPDecimalFromFloat(0.0) length:CPDecimalFromFloat(3.0 + 2.0*rand()/RAND_MAX)];
    plotSpace.yRange = [CPPlotRange plotRangeWithLocation:CPDecimalFromFloat(0.0) length:CPDecimalFromFloat(50 + 2.0*rand()/RAND_MAX)];
}

#pragma mark -
#pragma mark Plot Data Source Methods

-(NSUInteger)numberOfRecordsForPlot:(CPPlot *)plot {
    return [dataForPlot count];
}

-(NSNumber *)numberForPlot:(CPPlot *)plot field:(NSUInteger)fieldEnum recordIndex:(NSUInteger)index 
{
    NSNumber *num = [[dataForPlot objectAtIndex:index] valueForKey:(fieldEnum == CPScatterPlotFieldX ? @"x" : @"y")];
	// Green plot gets shifted above the blue
	if ([(NSString *)plot.identifier isEqualToString:@"Green Plot"])
	{
		if ( fieldEnum == CPScatterPlotFieldY ) 
			num = [NSNumber numberWithDouble:[num doubleValue] + 1.0];
	}
    return num;
}

#pragma mark -

/*
 // The designated initializer.  Override if you create the controller programmatically and want to perform customization that is not appropriate for viewDidLoad.
 - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
 if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])) {
 // Custom initialization
 }
 return self;
 }
 */

/*
 // Implement loadView to create a view hierarchy programmatically, without using a nib.
 - (void)loadView {
 }
 */

/*
 // Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
 - (void)viewDidLoad {
 [super viewDidLoad];
 }
 */

/*
 // Override to allow orientations other than the default portrait orientation.
 - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
 // Return YES for supported orientations
 return (interfaceOrientation == UIInterfaceOrientationPortrait);
 }
 */

- (void)didReceiveMemoryWarning {
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];
    
    // Release any cached data, images, etc that aren't in use.
}

- (void)viewDidUnload {
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}


-(void)dealloc 
{
	[dataForPlot release];
	[xAxisLabels release];
    [super dealloc];
}

@end
